/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Emprestimo;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import Empregado.Excecao;

/**
 *
 * @author igor
 */
public class Emprestimo {

    public static final String IDADE_INVALIDA = "IDADE DO EMPREGADO DO INSUFICIENTE PARA EMPRESTIMO !!!!";
    public static final String CREDITO_APROVADO = "APROVADO";
    public static final String CREDITO_REPROVADO = "REPROVADO";
    public static final int IDADE_MINIMA_EMPRESTIMO = 21;
    public static final int IDADE_MAXIMA_HOMEM = 65;
    public static final int IDADE_MAXIMA_MULHER = 61;
    private String cpf;
    private String nome;
    private BigDecimal valorSolicitado;
    private int numPrestacao;
    private double taxaJuros;
    private BigDecimal valorPrestacao;
    private double limiteMAXIMO;
    private String status;

    public Emprestimo() {
    }

    public Emprestimo(String CPF, String NOME, BigDecimal CREDITO, int PRESTACAO) {
        this.cpf = CPF;
        this.nome = NOME;
        this.valorSolicitado = CREDITO;
        this.numPrestacao = PRESTACAO;
        this.taxaJuros = (0.0); //taxa de juros
        this.valorPrestacao = new BigDecimal(0.0);
        this.limiteMAXIMO = 0.0;
        this.status = "              ";
    }

    public String getCpf() {
        return cpf;
    }

    public void setCpf(String cpf) {
        this.cpf = cpf;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public BigDecimal getValorSolicitado() {
        return valorSolicitado.setScale(2, RoundingMode.FLOOR);
    }

    public void setValorSolicitado(BigDecimal valorSolicitado) {
        this.valorSolicitado = valorSolicitado;
    }

    public int getNumPrestacao() {
        return numPrestacao;
    }

    public void setNumPrestacao(int numPrestacao) {
        this.numPrestacao = numPrestacao;
    }

    public double getTaxaJuros() {
        return taxaJuros;
    }

    public void setTaxaJuros(double taxaJuros) {
        this.taxaJuros = taxaJuros;
    }

    public BigDecimal getValorPrestacao() {
        return valorPrestacao.setScale(2, RoundingMode.FLOOR);
    }

    public void setValorPrestacao(BigDecimal valorPrestacao) {
        this.valorPrestacao = valorPrestacao;
    }

    public double getLimiteMAXIMO() {
        return limiteMAXIMO;
    }

    public void setLimiteMAXIMO(double limiteMAXIMO) {
        this.limiteMAXIMO = limiteMAXIMO;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public int calculaIdade(Date dataNasc) {
        int idade = 0;

        Date hoje = new Date();

        if (hoje.getYear() > dataNasc.getYear()) {
            idade = hoje.getYear() - dataNasc.getYear();
            if (hoje.getMonth() + 1 < dataNasc.getMonth() + 1) {
                idade--;
            } else if (hoje.getMonth() + 1 == dataNasc.getMonth() + 1) {
                if (hoje.getDate() < dataNasc.getDate()) {
                    idade--;
                }
            }
        }

        return idade;

    }

    public static BigDecimal calculaValorPrestacao(double taxaJuros, int numPrestacao, BigDecimal valorSolicitado) {

        double CF = taxaJuros / (1.0 - (1.0 / (Math.pow((1.0 + taxaJuros), numPrestacao))));

        BigDecimal converteCF = BigDecimal.valueOf(CF);

        BigDecimal parcela = (valorSolicitado.multiply(converteCF));

        return parcela;

    }

    public static double calculaTaxa(int numPrest) {
        // taxa de juros para 0 a 24 prestações
        double[] taxa = {0.00, .05, .05, .05, .065, .065, .065, .065, .065, .065, .08, .08, .08, .08, .08, .08, .10, .10, .10, .10, .10, .10, .10, .10, .10};

        return taxa[numPrest];

    }

    public double limiteMaximo(String sexo, int idade, BigDecimal salario) throws Excecao {

        // Se for Mulher - sexo = "F"
        if (sexo.equals("F")) {
            double[] percF = {0.70, 0.70, 0.70, 0.70, 0.70, 0.70, 0.70, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35};

            if (idade < IDADE_MINIMA_EMPRESTIMO || idade > IDADE_MAXIMA_MULHER) {
                throw new Excecao(IDADE_INVALIDA);
            } else {
                limiteMAXIMO = percF[idade - IDADE_MINIMA_EMPRESTIMO];
            }

        } else // Se for Homem - sexo = "M"
        {
            if (idade < IDADE_MINIMA_EMPRESTIMO || idade > IDADE_MAXIMA_HOMEM) {
                throw new Excecao(IDADE_INVALIDA);
            } else if (salario.compareTo(BigDecimal.valueOf(6000)) > 0) {
                // Faixa Homem 21a35 salario>5000 + Faixa Homem 36a45 salario>6000 + Faixa Homem 46a65
                double[] percH6000 = {0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.60, 0.60, 0.60, 0.60, 0.60, 0.60, 0.60, 0.60, 0.60, 0.60, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30};
                limiteMAXIMO = percH6000[idade - IDADE_MINIMA_EMPRESTIMO];
            } else if (salario.compareTo(BigDecimal.valueOf(5000)) > 0) {
                // Faixa Homem 21a35 salario>5000 + Faixa Homem 36a45 + Faixa Homem 46a65
                double[] percH5000 = {0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30};
                limiteMAXIMO = percH5000[idade - IDADE_MINIMA_EMPRESTIMO];
            } else {
                // Faixa Homem 21a35 + Faixa Homem 36a45 + Faixa Homem 46a65
                double[] percH5000 = {0.70, 0.70, 0.70, 0.70, 0.70, 0.70, 0.70, 0.70, 0.70, 0.70, 0.70, 0.70, 0.70, 0.70, 0.70, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30};
                limiteMAXIMO = percH5000[idade - IDADE_MINIMA_EMPRESTIMO];
            }

        }

        return limiteMAXIMO;

    }

    public static Emprestimo solicitaEmp(String cpf, BigDecimal valorSoli, int numPrest) throws Excecao {

        // Date dataHoje = new Date();
        Emprestimo e = null;

        //Recupera os dados de Empregados pelo CPF :
        // nome, sexo, dataNascimento  e salario
        Empregado.Empregado emp = new Empregado.Empregado();
        Empregado.Manutencao man = new Empregado.Manutencao();

        try {
            emp = man.retornaEmpregado(cpf);

        } catch (Excecao ex) {

            ex.getMessage();
            throw ex;//new Excecao("CPF nao encontrado!");
        }

        String nome = emp.getNome();
        String sexo = emp.getSexo();

        String dataNasc = emp.getDataNascimento();
        Date dataNascimento = new Date(dataNasc);

        BigDecimal salario = emp.getSalarioAtual();

        e = new Emprestimo(cpf, nome, valorSoli, numPrest);

        int idade = e.calculaIdade(dataNascimento);

        // Calculo do Limite Maximo do Emprestimo
        e.setLimiteMAXIMO(e.limiteMaximo(sexo, idade, salario));

        // Se valor solicitado > Limite Maximo de Emprestimo
        BigDecimal valorLimite = salario.multiply(BigDecimal.valueOf(e.getLimiteMAXIMO()));

        if (e.valorSolicitado.compareTo(valorLimite) > 0) {
            // Limite de emprestimo <= 0.00
            e.setStatus(CREDITO_REPROVADO);

        } else {
            e.setTaxaJuros(calculaTaxa(numPrest));
            e.setValorPrestacao(calculaValorPrestacao(e.getTaxaJuros(), numPrest, e.valorSolicitado));
            e.setStatus(CREDITO_APROVADO);
        }
        return e;
    }
}
